import 'dart:async';

import 'package:df/page/main/main_page.dart';
import 'package:df/page/login/wechat/scan_page.dart';
import 'package:df/page/register/register_page.dart';
import 'package:df/page/router/router_observer.dart';
import 'package:df/page/router/router_error_page.dart';
import 'package:df/page/login/login_page.dart';
import 'package:df/page/sms/code_page.dart';
import 'package:df/page/sms/sms_page.dart';
import 'package:df/page/splash/splash_page.dart';
import 'package:df/page/web/web_page.dart';
import 'package:df/page/web/test_web_page.dart';
import 'package:df/utils/logger_utils.dart';
import 'package:df/utils/sp_key.dart';
import 'package:df/utils/sp_utils.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:df/generated/l10n.dart';


//退出当前，页回到上一页                 GoRouter.of(context).pop(result)
//去下一页，弹出之前所有页                GoRouter.of(context).go(location)
//去下一页(根据名字)，弹出之前所有页       GoRouter.of(context).goNamed(name)
//去下一页                             GoRouter.of(context).push(location)
//去下一页(根据名字)                    GoRouter.of(context).pushNamed(name)
//去下一页，替掉当前页(放到栈顶)           GoRouter.of(context).pushReplacement(location)//通常用于在导航到新页面时替换当前页面，例如在登录成功后替换为主屏幕。
//去下一页(根据名字) ，替掉当前页(放到栈顶) GoRouter.of(context).pushReplacementNamed(name)
//去下一页，替掉当前页                   GoRouter.of(context).replace(location)
//去下一页(根据名字) ，替掉当前页         GoRouter.of(context).replaceNamed(name)
class RouterId {
  static String? wechatUnionId;
  static String? larkUnionId;
  static String? userId;

  static saveId(String? wechatId, String? larkId, String? id) {
    wechatUnionId = wechatId;
    larkUnionId = larkId;
    userId = id;
    SpUtils().set(SpKey.kSpWechatUnionId, wechatUnionId);
    SpUtils().set(SpKey.kSpLarkUnionId, larkUnionId);
    SpUtils().set(SpKey.kSpUserId, userId);
  }
}

const String ROUTER_SPLASH = 'splash';
const String ROUTER_SPLASH_PATH = '/';
const String ROUTER_WEB = 'web';
const String ROUTER_WEB_PATH = '/${ROUTER_WEB}';
const String ROUTER_LOGIN = 'login';
const String ROUTER_LOGIN_PATH = '/${ROUTER_LOGIN}';
const String ROUTER_SCAN = 'scan';
const String ROUTER_SCAN_PATH = '/${ROUTER_SCAN}';
const String ROUTER_SMS = 'sms';
const String ROUTER_SMS_PATH = '/${ROUTER_SMS}';
const String ROUTER_CODE = 'code';
const String ROUTER_CODE_PATH = '/${ROUTER_CODE}';
const String ROUTER_REGISTER = 'register';
const String ROUTER_REGISTER_PATH = '/${ROUTER_REGISTER}';
const String ROUTER_USER = 'user';
const String ROUTER_USER_PATH = '/${ROUTER_USER}';
const String ROUTER_CAMERA = 'camera';
const String ROUTER_CAMERA_PATH = '/${ROUTER_CAMERA}';

const String key_location = 'location';
const String key_text = 'text';


final router = GoRouter(
//List<RouteBase> routes: 这是一个包含路由配置信息的列表，每个元素都是一个 RouteBase 对象，定义了不同路径的构建器和嵌套路由。每个 RouteBase 通常是一个 GoRoute 对象，用于表示不同的页面或路由。
// GoRouterPageBuilder? errorPageBuilder: 这是一个可选的参数，用于定义在出现错误时要显示的错误页面的构建器。如果在导航过程中出现了错误，errorPageBuilder 将被用来构建错误页面。
// GoRouterWidgetBuilder? errorBuilder: 这也是一个可选参数，用于定义在出现错误时要显示的错误小部件的构建器。与 errorPageBuilder 类似，但返回的是一个小部件而不是页面。
// GoRouterRedirect? redirect: 这是一个可选参数，用于定义重定向逻辑。如果设置了 redirect，则在导航时，它可以根据某些条件将用户重定向到其他路径。
// Listenable? refreshListenable: 这是一个可选参数，如果提供，将在监听到 refreshListenable 发生变化时刷新路由。
// int redirectLimit = 5: 这是一个可选参数，指定重定向的最大次数。如果达到重定向次数上限，将不再进行重定向，以防止无限循环。
// bool routerNeglect = false: 这是一个可选参数，如果设置为 true，则忽略所有的路由。在某些情况下，你可能想要暂时禁用路由，而不是完全删除它们。
// String? initialLocation: 这是一个可选参数，用于指定应用程序的初始位置。当应用程序启动时，它将导航到这个位置。
// List<NavigatorObserver>? observers: 这是一个可选参数，用于提供导航观察者的列表。导航观察者可以用于监听导航过程中的事件，例如路由推送、弹出等。
// bool debugLogDiagnostics = false: 这是一个可选参数，如果设置为 true，则在调试模式下输出诊断信息，用于帮助调试路由问题。
// GlobalKey<NavigatorState>? navigatorKey: 这是一个可选参数，用于提供一个全局的 NavigatorState 键，以便于在整个应用程序中访问导航器状态。
// String? restorationScopeId: 这是一个可选参数，用于标识导航栈的恢复范围。用于将导航栈的状态保存和恢复。
    initialLocation: ROUTER_SPLASH_PATH,//(可选)路由初始页面
    errorBuilder: (context, GoRouterState state) {//(可选)出现错误显示错小部件(不是页面)
      return const RouterErrorPage();
    },
//errorPageBuilder: ,//(可选)路由错误页面
    debugLogDiagnostics: true,//(可选)调试路由
    observers: [MyNavObserver()],//【】//(可选)监听事件：推送、弹出
    routes: [
      GoRoute(
        //required String path： 必需的参数，表示当前路由的路径。它是一个字符串，用于唯一标识这个路由。例如，'/details'。
        // String? name： 可选参数，表示当前路由的名称。名称是一个字符串，可用于在路由树中标识这个路由。通常情况下，路径就足够唯一标识路由，但如果需要，你可以提供一个额外的名称。
        // WidgetBuilder? builder： 可选参数，一个 WidgetBuilder，用于在导航到此路由时构建路由的内容。这是一个函数，接受 BuildContext 和 GoRouterState 作为参数，并返回一个 Widget。
        // GoRouterPageBuilder? pageBuilder： 可选参数，一个 GoRouterPageBuilder，用于构建页面。类似于 builder，但允许更多的配置选项，例如页面过渡动画等。
        // GlobalKey<NavigatorState>? parentNavigatorKey： 可选参数，一个 GlobalKey<NavigatorState>，用于在构建当前路由时设置父导航器的键。这对于在路由树之间共享导航状态很有用。
        // GoRouterRedirect? redirect： 可选参数，用于定义在导航到当前路由时是否要重定向到其他路径。这是一个函数，接受 GoRouterState 作为参数，并返回一个字符串路径。
        // super.routes = const <RouteBase>[]： super 关键字用于调用父类（RouteBase）的构造函数。这个参数用于传递当前路由包含的子路由，以构建嵌套的路由结构。在这里，通过将 super.routes 设置为一个空的 List，表示当前路由不包含任何子路由。
        path: ROUTER_SPLASH_PATH,
        name: ROUTER_SPLASH,
        // builder: (_, state) => const LoginPage(title: '标题'),
        // builder: (_, state) => const WebPage(title: '标题'),
        builder: (context, GoRouterState goRouterState) {
          /// 6->7
          // GoRouteState.subloc 已重命名为 GoRouteState.matchedLocation。
          // GoRouteState.params 已重命名为 GoRouteState.pathParameters。
          // GoRouteState.fullpath 已重命名为 GoRouteState.fullPath。
          // GoRouteState.queryParams 已重命名为 GoRouteState.queryParameters。
          // GoRouteState.namedLocation 中的 params 和 queryParams 已重命名为 pathParameters 和 queryParameters。
          // GoRouter的namedLocation、pushNamed、pushReplacementNamed、replaceNamed中的params和queryParams已重命名为pathParameters和queryParameters。
          // BuildContext 的namedLocation、pushNamed、pushReplacementNamed 和replaceNamed 中的params 和queryParams 已重命名为pathParameters 和queryParameters。
          /// 9->10
          //将 GoRouterState 中的 location、queryParameters 和 queryParametersAll 替换为 uri
          // String? id = state.queryParameters['id'];
          return SplashPage();
        },
      ),

      GoRoute(
          path: ROUTER_WEB_PATH,
          name: ROUTER_WEB,
          builder: (_, GoRouterState state) {
            Map<String, String> queryParameters = state.uri.queryParameters;
            String? wechatUnionId = queryParameters[SpKey.kSpWechatUnionId];
            String? larkUnionId = queryParameters[SpKey.kSpLarkUnionId];
            String? userId = queryParameters[SpKey.kSpUserId];
            LogUtils.w('【参数】\n 传参(微信)Id= ${wechatUnionId}\n SpId= ${RouterId.wechatUnionId}');
            LogUtils.w('【参数】\n 传参(飞书)Id= ${larkUnionId}\n SpId= ${RouterId.larkUnionId}');
            LogUtils.w('【参数】\n 传参(用户)Id= ${userId}\n SpId= ${RouterId.userId}');

            if(true) {
              return MainPage(
                wechatUnionId: wechatUnionId ?? (RouterId.wechatUnionId ?? ''),
                larkUnionId: larkUnionId ?? (RouterId.larkUnionId ?? ''),
                userId: userId ?? (RouterId.userId ?? ''),
              );
            } else {
              return WebPage(
                wechatUnionId: wechatUnionId ?? (RouterId.wechatUnionId ?? ''),
                larkUnionId: larkUnionId ?? (RouterId.larkUnionId ?? ''),
                userId: userId ?? (RouterId.userId ?? ''),
              );
            }

          },
          redirect: loginRedirect
      ),

      GoRoute(
        path: ROUTER_LOGIN_PATH,
        name: ROUTER_LOGIN,
        builder: (_, GoRouterState state) {
          return LoginPage(title: S.current.login);
        },
      ),

      GoRoute(
        path: ROUTER_SMS_PATH,
        name: ROUTER_SMS,
        builder: (_, GoRouterState state) {
          return SmsPage();
        },
      ),
      GoRoute(
        path: ROUTER_CODE_PATH,
        name: ROUTER_CODE,
        builder: (_, GoRouterState state) {
          return CodePage();
        },
      ),


      GoRoute(
        path: ROUTER_REGISTER_PATH,
        name: ROUTER_REGISTER,
        builder: (_, GoRouterState state) {
          return RegisterPage();
        },
      ),

      GoRoute(
        path: ROUTER_CAMERA_PATH,
        name: ROUTER_CAMERA,
        builder: (_, GoRouterState state) {
          return TestWebPage(
              wechatUnionId: '1',
              larkUnionId: '2',
              userId: '3');
        },
      ),

      GoRoute(
        path: ROUTER_SCAN_PATH,
        name: ROUTER_SCAN,
        builder: (_, GoRouterState state) {
          return ScanPage();
        },
      ),

    ]
);

FutureOr<String?> loginRedirect(BuildContext context, GoRouterState goRouterState) {
  String? goRouterName = goRouterState.name;
  String? goRouterLocation = goRouterState.matchedLocation;
  Map<String, String> queryParameters = goRouterState.uri.queryParameters;

  String? wechatUnionId;
  String? larkUnionId;
  String? userId;
  if(queryParameters.isNotEmpty) {
    wechatUnionId = queryParameters[SpKey.kSpWechatUnionId];
    larkUnionId = queryParameters[SpKey.kSpLarkUnionId];
    userId = queryParameters[SpKey.kSpUserId];
  } else {
    RouterId.wechatUnionId = SpUtils().get<String?>(SpKey.kSpWechatUnionId);
    RouterId.larkUnionId = SpUtils().get<String?>(SpKey.kSpLarkUnionId);
    RouterId.userId = SpUtils().get<String?>(SpKey.kSpUserId);
    LogUtils.v('【SP】初始化并取(微信)Id：${RouterId.wechatUnionId}');
    LogUtils.v('【SP】初始化并取(飞书)Id：${RouterId.larkUnionId}');
    LogUtils.v('【SP】初始化并取(用户)Id：${RouterId.userId}');

    wechatUnionId = RouterId.wechatUnionId;
    larkUnionId = RouterId.larkUnionId;
    userId = RouterId.userId;
  }
  bool isAllEmpty = (wechatUnionId == null || wechatUnionId.isEmpty) && (larkUnionId == null || larkUnionId.isEmpty) && (userId == null || userId.isEmpty);
  LogUtils.i('【路由】Id(全)为空= ${isAllEmpty}');
  LogUtils.i('【路由】微信Id不为空= ${wechatUnionId}');
  LogUtils.i('【路由】飞书Id不为空= ${larkUnionId}');
  LogUtils.i('【路由】用户Id不为空= ${userId}');

  //如果没登录,并且当前不在登录页面,去登录 (并将本来想要跳转的页面传递到登录页)
  final noRouterLogin = goRouterLocation != ROUTER_LOGIN_PATH;
  LogUtils.i('【路由】(不是)登录页= ${noRouterLogin}\n ${goRouterLocation}');

  if (isAllEmpty && noRouterLogin) {
    String? location = goRouterState.uri.toString();
    //String? location = goRouterState.location;
    LogUtils.v('【路由】重定向去登录= ${location}');

    return goRouterState.namedLocation(//命名(重定向)路由
        ROUTER_LOGIN, //名称
        queryParameters: { //参数
          key_location: location,
          key_text: '未登录无法跳转',
        });
    //return '/login?location=${state.location}';
  } else {
    FutureOr<String?> location = null;
    // if(goRouterName == ROUTER_WEB || goRouterLocation == ROUTER_WEB_PATH) {
    //   LogUtils.w('【路由】重定向去(非)Web页= ${ROUTER_WEB}');
    //
    //   location = goRouterState.namedLocation(//命名(重定向)路由
    //       ROUTER_WEB, //名称
    //       queryParameters: { //参数
    //         kRouterWechatUnionId: wechatUnionId ?? '',
    //         kRouterLarkUnionId: larkUnionId ?? '',
    //         kRouterUserId: userId ?? '',
    //       });
    // } else {
    //   LogUtils.w('【路由】重定向去(非)登录= ${goRouterLocation}');
    // }

    return location;
  }
}
